#include "appinc.h"
#include "sans_demo.h"

struct {
	int sid;
	char *fileid;
	int size;
}ota_s;

char *sw_version = "V1.0.0_230101";

int sans_ota_report(void *obj, int step, const char *desc)
{
	cJSON *resp, *data;
	int ret;
	char *str_send;

	if (step > 100 || step < -4)
		return -EINVAL;

	resp = cJSON_CreateObject();
	if (resp == NULL)
		return -ENOMEM;
	data = cJSON_CreateObject();
	if (data == NULL) {
		cJSON_Delete(resp);
		return -ENOMEM;
	}
	cJSON_AddNumberToObject(data, "step", step);
	if (desc)
		cJSON_AddStringToObject(data, "desc", desc);

	cJSON_AddNumberToObject(resp, "sid", ota_s.sid);
	cJSON_AddItemToObject(resp, "data", data);

	str_send = cJSON_PrintUnformatted(resp);
	cJSON_Delete(resp);
	if (str_send == NULL)
		return -ENOMEM;

	ret = ssiot_publish(NULL, "ota/progress", str_send, strlen(str_send));
	free(str_send);

	return ret;
}

void *ota_func(void *arg)
{
	int ret;
	uint8_t *buf;

	buf = malloc(ota_s.size + 4);
	ret = sans_file_download(ota_s.fileid, buf, ota_s.size, 60);
	if (ret < 0) {
		sans_ota_report(NULL, -2, "download fail");
	} else {
		//todo 执行升级
		sans_ota_report(NULL, -0, NULL);
	}
	ota_s.fileid = NULL;

	return (void *)0;
}


int sans_ota_request(void *obj, ssiot_message_t *msg, cJSON *data)
{
	char *fileid = NULL;
	pthread_t thread;
	int size;

	//demo代码只实现fileid方式下载文件
	if (data) {
		cJSON *tmp;
		tmp = cJSON_GetObjectItem(data, "fileid");
		if (tmp) fileid = tmp->valuestring;
		tmp = cJSON_GetObjectItem(data, "size");
		if (tmp) size = tmp->valueint;
	}
	if (fileid == NULL || size <= 0) {
		msg->resp_code = SSCODE_ERR_REQUEST;
		msg->resp_msg = "request invalid";
		return -EFAULT;
	}
	if (ota_s.fileid) {
		msg->resp_code = SSCODE_ERR_REQUEST;
		msg->resp_msg = "upgrade busy";
		return -EFAULT;
	}
	
	LOG_D("server upgrade request!!");
	ota_s.sid = msg->sid;
	ota_s.fileid = strdup(fileid);
	ota_s.size = size;
	pthread_create(&thread, NULL, ota_func, obj);
	pthread_detach(thread);

	msg->resp_code = SSCODE_OK;

	return 0;
}



int sans_ota(void *obj, const char *topic, ssiot_message_t *msg)
{
	if (!strcmp(topic, "upgrade"))
		return sans_ota_request(obj, msg, msg->data);

	return -1;
}


int sans_ota_inform(void)
{
	char data[64];

	snprintf(data, sizeof(data), TOSTR({"data":{"main":"%s"}}), sw_version);
	return ssiot_publish(NULL, "ota/inform", data, strlen(data));
}




